package com.example.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    /**
     * 创建 StringRedisTemplate，使用默认的 LettuceConnectionFactory
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        return new StringRedisTemplate(lettuceConnectionFactory);
    }

    /**
     * 创建默认的 LettuceConnectionFactory 配置
     */
    @Bean
    @Primary
    public LettuceConnectionFactory defaultRedisConnectionFactory(RedisProperties redisProperties) {
        return createLettuceConnectionFactory(redisProperties);
    }

    /**
     * 创建 RedisTemplate，使用默认的 Redis 连接
     */
    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory defaultRedisConnectionFactory) {
        return createRedisTemplate(defaultRedisConnectionFactory);
    }

    /**
     * 创建活动 Redis 的 LettuceConnectionFactory
     */
    @Bean
    public LettuceConnectionFactory activityRedisConnectionFactory(ActivityRedisProperties redisProperties) {
        return createLettuceConnectionFactory(redisProperties);
    }

    /**
     * 创建活动 RedisTemplate
     */
    @Bean(name = "activityRedisTemplate")
    public RedisTemplate<String, Object> activityRedisTemplate(LettuceConnectionFactory activityRedisConnectionFactory) {
        return createRedisTemplate(activityRedisConnectionFactory);
    }

    /**
     * 创建会话 Redis 的 LettuceConnectionFactory
     */
    @Bean
    public LettuceConnectionFactory sessionRedisConnectionFactory(SessionRedisProperties redisProperties) {
        return createLettuceConnectionFactory(redisProperties);
    }

    /**
     * 创建会话 RedisTemplate
     */
    @Bean(name = "sessionRedisTemplate")
    public RedisTemplate<String, Object> sessionRedisTemplate(LettuceConnectionFactory sessionRedisConnectionFactory) {
        return createRedisTemplate(sessionRedisConnectionFactory);
    }

    /**
     * 创建 PKGame Redis 的 LettuceConnectionFactory
     */
    @Bean
    public LettuceConnectionFactory pkGameRedisConnectionFactory(PKGameRedisProperties redisProperties) {
        return createLettuceConnectionFactory(redisProperties);
    }

    /**
     * 创建 PKGame RedisTemplate
     */
    @Bean(name = "pkGameRedisTemplate")
    public RedisTemplate<String, Object> pkGameRedisTemplate(LettuceConnectionFactory pkGameRedisConnectionFactory) {
        return createRedisTemplate(pkGameRedisConnectionFactory);
    }

    /**
     * 创建 LettuceConnectionFactory 的公共方法
     */
    private LettuceConnectionFactory createLettuceConnectionFactory(BaseRedisProperties redisProperties) {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(redisProperties.getHost());
        config.setPort(redisProperties.getPort());
        config.setDatabase(redisProperties.getDb());
        config.setPassword(redisProperties.getPassword());
        return new LettuceConnectionFactory(config);
    }

    /**
     * 创建 RedisTemplate 的公共方法，并设置序列化器
     */
    private RedisTemplate<String, Object> createRedisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        // 设置键和值的序列化器为 StringRedisSerializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        template.setHashValueSerializer(stringRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }
}
